#include <scn.h>

#include <errno.h>
#include <string.h>
#include <debug.h>
#include <coord.h>

#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>


model3d_t *
scn_load( const char *filename )
{
  model3d_t *m = NULL;
  char scn[ 4 ];
  unsigned cx, cy, cz;
  size_t size;
  FILE *fp;
  int n;
  struct stat fs;

  fp = fopen( filename, "r" );
  if ( fp == NULL )
    {
      err( "Could not open file \"%s\": %s\n", filename, strerror( errno ) );
      return NULL;
    }

  if ( fscanf( fp, "%3s", scn ) != 1 )
    {
      err( "Reached end of file sooner than expected!\n" );
      fclose( fp );
      return NULL;
    }
  if ( strcmp( "SCN", scn ) != 0 )
    {
      err( "Expected \"SCN\", got \"%s\"!\n", scn );
      fclose( fp );
      return NULL;
    }

  if ( ( n = fscanf( fp, "%u %u %u", &cx, &cy, &cz ) ) != 3 )
    {
      err( "Reached end of file sooner than expected!"
	   "Read %d arguments of 3 required.\n", n );
      fclose( fp );
      return NULL;
    }

  if ( fstat( fileno( fp ), &fs ) != 0 )
    {
      err( "Could not stat file \"%s\": %s\n", filename, strerror( errno ) );
      fclose( fp );
      return NULL;
    }

  size = cx * cy * cz;
  off_t offset = fs.st_size - size * sizeof(*m->buffer);

  if ( offset < 0 )
    {
      err( "Invalid file size: %ld, need at least %d\n", fs.st_size, size );
      fclose( fp );
      return NULL;
    }

  fseek( fp, offset, SEEK_SET );

  m = model3d_new( cx, cy, cz );
  if ( ( n = fread( m->buffer, sizeof(*m->buffer), size, fp ) ) != size )
    {
      err( "Could not load entire data! Read %d from %d.\n", n, size );
      fclose( fp );
      return NULL;
    }

  fclose( fp );
  return m;
}
